/*
 * HTTPRequest.fx
 *
 * Created on 11-dec-2009, 9:59:32
 */

package javafx_20092010_reeks2.michaelpontus;

import javafx.io.http.HttpRequest;
import java.io.File;
import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import javafx.io.http.HttpHeader;
import javafx.date.DateTime;
import javafx.data.Pair;

/**
 * HttpRequest able to upload files to a given url
 *
 * @author jan
 */

def PREFIX = "--";

def NEWLINE = "\r\n";

def BOUNDARY = createBoundary();

def CONTENT_TYPE = "multipart/form-data; boundary={BOUNDARY}";

def NAME = "upfile";

function createBoundary() :String {
    def now = DateTime {};
    return "{Long.toHexString(now.instant)}";
}

public class HTTPRequest extends HttpRequest {

    // A sequence of files to upload
    public-init var file:File;

    // Fields to upload together with the request

    postinit{

        // we always do a post
        method = HttpRequest.POST;

        // override the onOutput
        onOutput = writeFiles;

        // add the headers we need
        insert HttpHeader {
            name:HttpHeader.ACCEPT
            value: "*/*"
        } into headers;
        insert HttpHeader {
            name:HttpHeader.CONTENT_TYPE
            value: CONTENT_TYPE
        } into headers;
        insert HttpHeader {
            name:HttpHeader.CONNECTION
            value: "keep-alive"
        } into headers;
        insert HttpHeader {
            name:HttpHeader.CACHE_CONTROL
            value: "no-cache"
        } into headers;
        insert HttpHeader {
            name:HttpHeader.ACCEPT_CHARSET
            value: "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
        } into headers;
    }

    function writeFiles( output:OutputStream ) {
       println("here1");

       try {
            // send the files
            println("here2");
            if ( file != null and sizeof file > 0 ) {
                println("here3");
                
                    // leading characters
                    output.write(PREFIX.getBytes());
                    output.write(BOUNDARY.getBytes());
                    output.write(NEWLINE.getBytes());
                    output.write("Content-Disposition: form-data; name=\"{NAME}\"; filename=\"{file.getName()}\"".getBytes());
                    output.write(NEWLINE.getBytes());
                    output.write("Content-Type: application/octet-stream".getBytes());
                    output.write(NEWLINE.getBytes());
                    output.write(NEWLINE.getBytes());

                    // write the file's content on the wire - use a native array of byte
                    // in order to use Java's IO classes
                    var buffer = IOUtils.createByteBuffer(10240);
                    var input = new BufferedInputStream( new FileInputStream( file ) );
                    var eof = false;
                    try {
                        while ( true ) {
                            var read = input.read(buffer);
                            if ( read > 0 ) {
                                output.write(buffer, 0, read);
                                println("here4");
                            }
                            else {
                                break;
                            }
                        }
                    } finally {
                        input.close();
                    }

                    // end of file
                    output.write(NEWLINE.getBytes());
                    output.flush();
                
                output.write(NEWLINE.getBytes());
            }
            output.write(PREFIX.getBytes());
            output.write(BOUNDARY.getBytes());
            output.write(PREFIX.getBytes());
            output.write(NEWLINE.getBytes());

        } finally {
                println("here5");
            output.flush();
            output.close();
        }
    }
}
